<template>
  <div class="kr-list-table-box" ref="krListTableBox">
    <div class="list-table-header" :class="listTableHeaderClass" ref="listTableHeader" v-if="searchObj.searchArr.length!=0">
      <div
        class="list-table-search"
        :class="{'search--btnOverflow':actionBtnIfBlock}"
        ref="krListTableSearch"
      >
        <div v-for="(searchItem,index) in searchList" :key="index" class="list-table-search--item">
          <label class="item-label">{{searchItem.label}}</label>
          <el-date-picker
            v-if="['date','week','month','year','datetime','daterange','datetimerange'].includes(searchItem.type)"
            class="item-input"
            v-model="searchForm[searchItem.model]"
            :title="searchForm[searchItem.model]"
            :type="searchItem.type"
            size="mini"
            @focus="focusInput(searchItem.model)"
            @blur="blurInput(searchItem.model)"
            @clear="clearInput(searchItem.model)"
            @change="changeInput(searchItem.model)"
            :placeholder="searchItem.placeholder||'选择日期'"
            range-separator="至"
            start-placeholder="开始日期"
            end-placeholder="结束日期"
            :picker-options="searchItem.pickerOptions"
            clearable
            :format="searchItem.dateFormat||dateFrm(searchItem.type)"
            :value-format="dateFrm(searchItem.type)"
          ></el-date-picker>
          <el-select
            v-else-if="searchItem.type == 'select'"
            class="item-input"
            v-model="searchForm[searchItem.model]"
            placeholder="请选择"
            size="mini"
            filterable
            clearable
            @focus="focusInput(searchItem.model)"
            @blur="blurInput(searchItem.model)"
            @clear="clearInput(searchItem.model)"
            @change="changeInput(searchItem.model)"
          >
            <el-option
              v-for="(selectOpItem,selectIndex) in searchItem.option"
              :key="'select'+selectIndex"
              :label="selectOpItem.name"
              :value="selectOpItem.value"
            ></el-option>
          </el-select>
          <el-input
            v-else
            size="mini"
            :placeholder="searchItem.placeholder"
            v-model="searchForm[searchItem.model]"
            clearable
            class="item-input"
            @focus="focusInput(searchItem.model)"
            @blur="blurInput(searchItem.model)"
            @clear="clearInput(searchItem.model)"
            @change="changeInput(searchItem.model)"
          >
            <el-button
              slot="append"
              v-if="searchItem.appendBtn"
              :icon="searchItem.appendBtn.icon||'el-icon-search'"
              @click="searchItem.appendBtn.method?searchItem.appendBtn.method():null"
            >搜索</el-button>
          </el-input>
          <el-button
            v-if="index+1==searchList.length"
            type="warning"
            ref="searchBtn"
            icon="el-icon-search"
            class="search-btn"
            size="mini"
            @click="searchData"
          >搜索</el-button>
        </div>
        <div
          class="search-up-down--btn"
          v-if="searchObj.searchArr.length>searchInputCount"
          @click="thisShowAllSearch=!thisShowAllSearch"
        >
          <i class="el-icon-arrow-up" v-if="thisShowAllSearch"></i>
          <i class="el-icon-arrow-down" v-else></i>
        </div>
      </div>
      <div class="table-search--action" :style="actionStyle" ref="tableSearchAction">
        <template v-for="(actionItem,actionIndex) in actionList">
          <el-button
            ref="actionBtn"
            :class="actionItem.icon"
            class="table-action-btn"
            :type="actionItem.color || 'primary'"
            :key="actionIndex"
            v-if="!actionItem.isHide"
            size="mini"
            @click="actionItem.method(actionItem.name)"
          >{{actionItem.name}}</el-button>
          
        </template>
        <slot name="actionAfter"></slot>
      </div>
    </div>
    <!-- 表格主体 -->
    <div class="list-table-main" ref="listTableMain">
      <el-table
        :data="tableData"
        v-if="computeTableHeight"
        border
        stripe
        :header-cell-style="headerCellStyle"
        :height="autoHeight||height||maxHeight||computeTableHeight"
        :cell-style="cellStyle||null"
        ref="krListTable"
        @expand-change="expandChange"
        @row-click="clickChange"
        @sort-change="sortChange"
        highlight-current-row
        row-key="id"
      >
        <el-table-column
          v-if="selectionShow"
          :selectable="selectableMethod||null"
          fixed="left"
          type="selection"
          width="55"
        ></el-table-column>
        <el-table-column v-if="showIndex || false" label="序号" type="index" width="55" fixed></el-table-column>
        <template v-if="type=='expand'">
          <el-table-column type="expand" align="center">
            <template slot-scope="scope">
              <div class="expandTable">
                <el-table
                  :data="expandData"
                  max-height="240"
                  border
                  stripe
                  :header-cell-style="headerCellStyle"
                  v-loading="expandLoading"
                  ref="expandTable"
                  :key="scope.row.id"
                  :cell-style="expandCellStyle||null"
                >
                  <el-table-column type="index" width="55" label="序号"></el-table-column>
                  <template v-for="(item,index) in expandColumn">
                    <el-table-column
                      :label="item.label"
                      :align="item.textAlign?item.textAlign:null"
                      :width="item.width"
                      :prop="item.prop"
                      v-if="!item.hide"
                      :key="'_'+index"
                    >
                      <template slot-scope="scope">
                        <template v-if="item.type=='button'">
                          <template v-for="(btnItem,btnIndex) in item.buttonArr">
                            <el-button
                              type="text"
                              size="small"
                              :key="btnIndex"
                              v-if="btnItem.isShow(scope.row)"
                              @click="btnItem.methods(scope.row)"
                              :icon="btnItem.icon"
                            >{{btnItem.text}}</el-button>
                          </template>
                        </template>
                        <span
                          :style="item.textStyle(scope.row)"
                          v-else-if="item.textFormatter"
                        >{{item.textFormatter(scope.row)}}</span>
                        <span
                          class="text-pre-wrap"
                          v-else
                        >{{ item.formatter?item.formatter(scope.row):formatterNull(scope.row[scope.column.property])}}</span>
                      </template>
                    </el-table-column>
                  </template>
                </el-table>
              </div>
            </template>
          </el-table-column>
        </template>
        <template v-for="(item,index) in column">
          <el-table-column
            :label="item.label"
            :align="item.textAlign?item.textAlign:null"
            :width="item.width"
            :prop="item.prop"
            :key="index"
            v-if="!item.hide"
            :fixed="item.fixed||null"
            :sortable="item.sortable"
          >
            <template v-if="item.subColumn">
              <template v-for="(subItem,subIndex) in item.subColumn">
                <el-table-column
                  :label="subItem.label"
                  :align="subItem.textAlign?subItem.textAlign:null"
                  :width="subItem.width"
                  :prop="subItem.prop"
                  :key="subIndex"
                  v-if="!subItem.hide"
                  :fixed="subItem.fixed||null"
                >
                  <template slot-scope="scope">
                    <template v-if="subItem.type=='button'">
                      <template v-for="(btnItem,btnIndex) in subItem.buttonArr">
                        <el-button
                          type="text"
                          size="small"
                          :key="btnIndex"
                          v-if="btnItem.isShow(scope.row)"
                          @click="btnItem.methods(scope.row)"
                          :icon="btnItem.icon"
                        >{{btnItem.text}}</el-button>
                      </template>
                    </template>
                    <template v-else>
                      <span
                        :style="subItem.textStyle(scope.row)"
                        v-if="subItem.textFormatter"
                      >{{subItem.textFormatter(scope.row)}}</span>
                      <el-tooltip
                        effect="dark"
                        v-if="subItem.showTooltip"
                        placement="top"
                        :content="subItem.formatter?subItem.formatter(scope.row):subItem.text?formatterNull(scope.row[subItem.text]):formatterNull(scope.row[scope.column.property])"
                      >
                        <span
                          class="table-cloumn__span--tooltip w100"
                          style="display:inline-block"
                        >{{ subItem.formatter?subItem.formatter(scope.row):subItem.text?formatterNull(scope.row[subItem.text]):formatterNull(scope.row[scope.column.property])}}</span>
                      </el-tooltip>
                      <span
                        v-else
                      >{{ subItem.formatter?subItem.formatter(scope.row):formatterNull(scope.row[scope.column.property])}}</span>
                    </template>
                  </template>
                </el-table-column>
              </template>
            </template>
            <template slot-scope="scope">
              <template v-if="item.type=='button'">
                <template v-for="(btnItem,btnIndex) in item.buttonArr">
                  <el-button
                    type="text"
                    size="small"
                    :key="btnIndex"
                    v-if="btnItem.isShow(scope.row)"
                    @click="btnItem.methods(scope.row)"
                    :icon="btnItem.icon"
                  >{{btnItem.text}}</el-button>
                </template>
              </template>
              <template v-else>
                <span
                  :style="item.textStyle(scope.row)"
                  v-if="item.textFormatter"
                >{{item.textFormatter(scope.row)}}</span>
                <el-tooltip
                  effect="dark"
                  v-if="item.showTooltip"
                  placement="top"
                  :content="item.formatter?item.formatter(scope.row):item.text?formatterNull(scope.row[item.text]):formatterNull(scope.row[scope.column.property])"
                >
                  <span
                    class="table-cloumn__span--tooltip w100"
                    style="display:inline-block"
                  >{{ item.formatter?item.formatter(scope.row):item.text?formatterNull(scope.row[item.text]):formatterNull(scope.row[scope.column.property])}}</span>
                </el-tooltip>
                <span
                  v-else
                  class="text-pre-wrap"
                >{{ item.formatter?item.formatter(scope.row):formatterNull(scope.row[scope.column.property])}}</span>
              </template>
            </template>
          </el-table-column>
        </template>
      </el-table>
      <div class="kr-table-pagination">
        <el-pagination
          v-if="showPagination"
          @size-change="handleSizeChange"
          @current-change="handleCurrentChange"
          :current-page="searchForm.page"
          :page-sizes="paginationObj.pageSizes"
          :page-size="searchForm.pageSize"
          layout="total, sizes, prev, pager, next, jumper"
          :total="totalNumber"
        ></el-pagination>
      </div>
    </div>
  </div>
</template>

<script>
export default {
  props: {
    showAllSearch: {
      type: Boolean,
      default: false,
    },
    searchObj: Object,
    height: [Number, String], //表格高度
    maxHeight: [Number, String], //最大高度
    //是否自动高度，即不设置
    autoHeight: {
      type: Boolean,
      default: false,
    },
    //显示序号
    showIndex: {
      type: Boolean,
      default: true,
    },
    //操作按钮列表
    actionList: {
      type: Array,
      default: () => {
        return [];
      },
    },
    //操作弹框式按钮列表
    suspendBtnList: {
      type: Array,
      default: () => {
        return [];
      },
    },
    //table没有竖边框
    noBorderRight: {
      type: Boolean,
      default: false,
    },
    //显示分页
    showPagination: {
      type: Boolean,
      default: true,
    },
    //分页对象
    paginationObj: {
      type: Object,
      default: () => {
        return { pageSizes: [15, 30, 50, 100] };
      },
    },
    //表格样式
    cellStyle: Function,
    //展开的表格样式
    expandCellStyle: Function,
    //表格数据
    tableData: Array,
    //表格总数
    totalNumber: {
      type: Number,
      default: 0,
    },
    //展开的表格数据
    expandData: Array,
    //表格栏位数组
    column: Array,
    //展开的表格栏位数组
    expandColumn: Array,
    //表格类型
    type: String,
    //是否显示选择框
    selectionShow: {
      type: Boolean,
      default: false,
    },
    selectableMethod: {
      type: Function,
      default: () => {
        return true;
      },
    },
  },
  data() {
    return {
      thisShowAllSearch: false, //是否显示完全部的按钮
      searchInputCount: 3, //一行最多显示的输入框数量
      searchForm: {
        //搜索的表单数据
        page: 1,
        pageSize: 15,
      },
      //操作按钮是否独立一行
      actionBtnIfBlock: false,
      //操作按钮的宽度
      actionWidth: 0,
      //整个表格宽度
      tableBoxWidth: 0,
      //表格loading
      expandLoading: false,
      //当前选中的行
      currentrow: {},
      //计算的高度
      computeTableHeight: 0,
      //排序字段
      searchOrder: "",
    };
  },
  computed: {
    //查询的输入框列表
    searchList() {
      //如果显示全部
      if (this.thisShowAllSearch) {
        return this.searchObj.searchArr;
      } else {
        return this.searchObj.searchArr.filter(
          (i, index) => index < this.searchInputCount
        );
      }
    },

    //表格头部样式
    headerCellStyle() {
      let style = {
        background: "#fafafa",
        color: "#333333",
        fontWeight: "bold",
        borderBottom: "1px solid #ebebeb",
        padding: 0,
      };
      if (this.noBorderRight) {
        style.borderRight = "none";
      }
      return style;
    },
    //头部样式,暂不用,已用class
    searchHeaderStyle() {
      //新增按钮和输入框不在一行的时候
      if (this.actionBtnIfBlock) {
        return {
          display: "block",
          position: "relative",
        };
      } else {
        return {
          display: "flex",
          position: "relative",
          justifyContent: "space-between",
          marginBottom: "16px",
          borderBottom: "1px solid #ccc",
        };
      }
    },
    //头部样式
    listTableHeaderClass() {
      return this.actionBtnIfBlock
        ? "header--btnOverflow"
        : "header--btnNoOver";
    },
    //搜索框样式,暂不用
    searchDivStyle() {
      //新增按钮和输入框不在一行的时候
      if (this.actionBtnIfBlock) {
        return {
          marginBottom: "16px",
          borderBottom: "1px solid #ccc",
          position: "relative",
        };
      } else {
        return {};
      }
    },
    //按钮样式
    actionStyle() {
      const allListLen = this.searchObj.searchArr.length,
        searchInputCount = this.searchInputCount,
        actionWidth = this.actionWidth,
        tableBoxWidth = this.tableBoxWidth;
      if (this.thisShowAllSearch && allListLen > searchInputCount) {
        //如果为展开，且剩余宽度可以支撑按钮的宽度，则按钮往上挤
        if (
          tableBoxWidth -
            (searchInputCount - (allListLen % searchInputCount)) * 320 +
            50 >
          actionWidth
        ) {
          return { position: "absolute", bottom: "10px", right: "0px" };
        }
      }
      return {
        paddingBottom: "10px",
      };
    },
  },
  watch: {
    "searchObj.queryData": {
      handler(val) {
        this.searchForm = Object.assign({}, this.searchForm, val);
      },
      deep: true,
    },
    //赋值展开的data后取消loading
    expandData: {
      handler(val) {
        this.expandLoading = false;
      },
      deep: true,
    },
    thisShowAllSearch() {
      this.adjustSize();
    },
  },
  created(){
    this.init();
  },
  mounted() {
    this.adjustSize();
    window.addEventListener("resize", this.adjustSize);
  },
  beforeDestroy() {
    window.removeEventListener("resize", this.adjustSize);
  },
  methods: {
    init() {
      //如果显示全部输入框
      this.showAllSearch && (this.thisShowAllSearch = this.showAllSearch);
      //赋值搜索表单
      this.searchForm = Object.assign(
        {},
        this.searchForm,
        this.searchObj.queryData
      );
    },
    //获取焦点时
    focusInput(model) {
      this.$emit("focusInput", model);
    },
    //失去焦点时
    blurInput(model) {
      this.$emit("blurInput", model);
    },
    //点击清空时
    clearInput(model) {
      this.$emit("clearInput", model);
    },
    //输入框失去焦点或用户按下回车时触发
    changeInput(model) {
      this.$emit("changeInput", model);
    },
    //日期数据处理
    dateFrm(type) {
      if (type === "date" || type === "daterange") {
        return "yyyy-MM-dd";
      } else if (type == "datetime" || type === "datetimerange") {
        return "yyyy-MM-dd HH:mm:ss";
      } else if (type == "month") {
        return "yyyy-MM";
      } else if (type == "year") {
        return "yyyy";
      } else {
        return "";
      }
    },
    //调整尺寸
    async adjustSize() {
      this.setSearchCount();
      await this.$nextTick();
      this.setTableHeight();
    },
    /**设置表格宽度问题 */
    setSearchCount() {
      //宽度减去按钮的宽度
      let searchBtnWidth = this.searchObj.searchArr.length !=0 ? this.$refs.searchBtn[0].$el.offsetWidth:0;
      let searchWidth = this.$refs.krListTableBox.offsetWidth - searchBtnWidth;
      this.tableBoxWidth = searchWidth;
      //如果不展开，则第一行得减除搜索按钮的宽度
      // if (!this.thisShowAllSearch) {
      //   searchWidth -= 50;
      // }
      this.searchInputCount = parseInt(searchWidth / 330);

      //计算所有按钮的宽度
      let actionWidth = 0;
      let actionBtnRefs = this.$refs.actionBtn;
      if (actionBtnRefs) {
        if (actionBtnRefs.length) {
          actionBtnRefs.map((i, index) => {
            actionWidth += i.$el.clientWidth;
            //多个按钮时，会有10px边距
            if (index > 0) {
              actionWidth += 10;
            }
          });
        } else {
          actionWidth = actionBtnRefs.clientWidth;
        }
      }
      this.actionWidth = actionWidth;
      //除去输入框+搜索按钮及边距，如果剩余宽度不足，则往下放按钮
      if (
        searchWidth -
          (this.searchList.length * 330 + searchBtnWidth) -
          actionWidth <
        0
      ) {
        this.actionBtnIfBlock = true;
      } else {
        this.actionBtnIfBlock = false;
      }
    },
    /**设置表格最大高度 */
    setTableHeight() {
      let height = this.height,
        maxHeight = this.maxHeight,
        autoHeight = this.autoHeight;
      if (!height && !maxHeight && !autoHeight) {
        let parentH = this.$refs.krListTableBox.parentElement.clientHeight; //表格父级高度
        let searchH = this.searchObj.searchArr.length !=0 ? this.$refs.listTableHeader.clientHeight:0;//表格搜索框高度
        parentH = parentH - searchH - 10 - 40 - 16; //边距、页码高度、预留边距
        this.computeTableHeight = parentH < 300 ? 300 : parentH;
      }
    },
    /**判断空值默认- */
    formatterNull(text) {
      if (text === null || text === undefined || text === "") {
        return "-";
      } else {
        return text;
      }
    },
    //查询数据
    searchData() {
      this.searchForm.page = 1;
      this.searchOrder = "";
      //清除排序状态
      this.$refs.krListTable.clearSort();
      this.searchObj.searchMethod(this.searchForm, this.searchOrder);
    },
    //表格页显示数量改变
    handleSizeChange(val) {
      this.searchForm.page = 1;
      this.searchForm.pageSize = val;
      this.searchObj.searchMethod(this.searchForm, this.searchOrder);
    },
    //表格页码改变
    handleCurrentChange(val) {
      this.searchForm.page = val;
      this.searchObj.searchMethod(this.searchForm, this.searchOrder);
    },
    //点击展开按钮
    expandChange(row, expanded) {
      if (this.currentrow) {
        if (this.currentrow.id != row.id) {
          this.expandLoading = false;
          this.$refs.krListTable.toggleRowExpansion(this.currentrow, false);
          this.$set(this, "currentrow", row);
          this.$emit("expandRow", row);
        } else {
          //this.expandLoading = false;
          this.$set(this, "currentrow", row);
          this.$emit("expandRow", row);
          return;
        }
      }
      this.$set(this, "currentrow", row);
      this.expandLoading = true;
      this.$emit("expandRow", row);
    },
    closeExpand(){
      this.$refs.krListTable.toggleRowExpansion({}, true);
    },
    //点击行
    clickChange(row) {
      if (this.currentrow) {
        if (this.currentrow.id != row.id) {
          this.$refs.krListTable.toggleRowExpansion(this.currentrow, false);
          this.$set(this, "currentrow", row);
        } else {
          this.$refs.krListTable.toggleRowExpansion(row, false);
          //this.currentrow = null;
          return;
        }
      }
      this.$refs.krListTable.toggleRowExpansion(row, true);
      this.$emit("clickRow",row);
    },
    //排序改变时
    sortChange({ column, prop, order }) {
      order = order || "";
      this.searchOrder = `${prop} ${order.replace("ending", "")}`;
      this.searchObj.searchMethod(this.searchForm, this.searchOrder);
    },
    //获取选中的数据
    getSelectData() {
      let arr = this.$refs.krListTable.selection;
      return JSON.parse(JSON.stringify(arr));
    },
  },
};
</script>

<style lang="less"  scoped>
.kr-list-table-box {
  width: 100%;
  height: 100%;
}
.header--btnOverflow {
  display: block;
  position: relative;
}
.header--btnNoOver {
  display: flex;
  position: relative;
  justify-content: space-between;
  margin-bottom: 16px;
  border-bottom: 1px solid #ccc;
}
.list-table-search {
  display: flex;
  flex-direction: row;
  flex-wrap: wrap;
}
.list-table-search .search-up-down--btn {
    width: 48px;
    height: 14px;
    line-height: 12px;
    background: #EEEEEE;
    border-radius: 0px 0px 8px 8px;
    text-align: center;
    position: absolute;
    left: 50%;
    bottom: -14px;
    cursor: pointer;
    transform: translateX(-50%);
 /*  width: 56px;
  height: 14px;
  text-align: center;
  position: absolute;
  cursor: pointer;
  box-sizing: border-box;
  border-bottom-right-radius: 6px;
  border-bottom-left-radius: 6px;
  bottom: -14px;
  left: 50%;
  transform: translateX(-50%);
  border: 1px solid #cccccc; */
}
.search--btnOverflow {
  margin-bottom: 16px;
  border-bottom: 1px solid @kr-border-sub-color;
  position: relative;
}
.list-table-search--item {
  display: flex;
  justify-content: space-between;
  margin-bottom: 10px;
  margin-right: 15px;
}
.list-table-search--item .item-label {
  width: @kr-list-input-label-width;
  padding-right: 10px;
  display: inline-block;
  //text-align: justify;
  line-height: 28px;
  text-align: right;
  //text-align-last: justify;
}
.list-table-search--item .item-input {
  width: @kr-list-input-width;
}
.list-table-search--item .search-btn {
  margin-left: 20px;
  color: #fff;
  width: @kr-btn-min-width;
  background-color: @kr-selected-color;
  border-color: @kr-selected-color;
}
.table-search--action {
  flex: 1;
  text-align: right;
}
.table-search--action .table-action-btn {
  min-width: @kr-btn-min-width;
}
.list-table-main .el-table {
  font-size: 14px;
  width: 100%;
}
.kr-list-table-box .kr-table-pagination {
  height: 40px;
  padding-top: 20px;
  text-align: right;
  //padding-right: 10px;
}
</style>